﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 多线程编程入门Thread_Task_async_await简单秒懂
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 单线程做菜(会卡界面,窗口不能拖动,其他按钮不能点击,因为这里用的主线程就是UI线程)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSingleThread_Click(object sender, EventArgs e)
        {
            Thread.Sleep(3000);
            MessageBox.Show("素材做好了", "友情提示");
            Thread.Sleep(5000);
            MessageBox.Show("荤菜做好了", "友情提示");
        }

        /// <summary>
        /// Thread创建线程(开了新线程不会卡界面了)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnThread_Click(object sender, EventArgs e)
        {
            Thread t1 = new Thread(_ =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("素材做好了", "友情提示");
                Thread.Sleep(5000);
                MessageBox.Show("荤菜做好了", "友情提示");
            });

            t1.Start();
        }

        /// <summary>
        /// Task创建线程(推荐这种方式创建线程,性能会更好,管理会更方便)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTask_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("素材做好了", "友情提示");
                Thread.Sleep(5000);
                MessageBox.Show("荤菜做好了", "友情提示");
            });
        }

        /// <summary>
        /// 两个线程同时处理(两个任务并行运行,好处是利用cpu的多核,每个核心做一个事情,可以大大提高效率)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnWith_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("素材做好了", "友情提示");
            });

            Task.Run(() =>
            {
                Thread.Sleep(5000);
                MessageBox.Show("荤菜做好了", "友情提示");
            });
        }

        /// <summary>
        /// 无顺序执行,这里会先执行主线程的"菜都做好了,大家快来吃饭!"
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNon_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("素材做好了", "友情提示");
            });

            Task.Run(() =>
            {
                Thread.Sleep(5000);
                MessageBox.Show("荤菜做好了", "友情提示");
            });

            MessageBox.Show("菜都做好了,大家快来吃饭!", "提示");
        }


        /// <summary>
        /// 异步,有顺序的执行,等待一个线程执行完了,才能继续往下面执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnNext_Click(object sender, EventArgs e)
        {
            await Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("素材做好了", "友情提示");
            });

            await Task.Run(() =>
            {
                Thread.Sleep(5000);
                MessageBox.Show("荤菜做好了", "友情提示");
            });

            MessageBox.Show("菜都做好了,大家快来吃饭!", "提示");

        }

        /// <summary>
        /// 两个线程并行处理完后再执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTongshi_Click(object sender, EventArgs e)
        {

            List<Task> ts = new List<Task>();

            ts.Add(Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("素材做好了", "友情提示");
            }));

            ts.Add(Task.Run(() =>
            {
                Thread.Sleep(5000);
                MessageBox.Show("荤菜做好了", "友情提示");
            }));

            //等待所有任务都执行完成后,再来做另外的事情
            Task.WhenAll(ts).ContinueWith(t =>  //t:是前一个任务里面的信息,也就是说后续的任务可以得到前一个任务里的信息
            {
                MessageBox.Show("菜都做好了,大家快来吃饭!", "提示");
            });

        }
    }
}
